package com.gitee.sop.sopauth.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.gitee.fastmybatis.core.query.Query;
import com.gitee.sop.file.AliOssProperties;
import com.gitee.sop.file.AliyunOssService;
import com.gitee.sop.mongodb.MongoQuery;
import com.gitee.sop.servercommon.bean.OpenContext;
import com.gitee.sop.servercommon.bean.ServiceContext;
import com.gitee.sop.servercommon.exception.ServiceException;
import com.gitee.sop.servercommon.util.Md5Util;
import com.gitee.sop.servercommon.util.ObjectUtil;
import com.gitee.sop.sopauth.enums.TemplateStatus;
import com.gitee.sop.sopauth.mapper.ResourceMapper;
import com.gitee.sop.sopauth.service.ISysFileService;
import com.gitee.sop.sopauth.util.FileUploadUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 阿里云 文件存储
 *
 * @author wlx
 */
@Service
public class AliOssSysFileServiceImpl extends BaseServiceImpl implements ISysFileService {
    @Resource
    private ResourceMapper resourceMapper;


    private AliyunOssService aliyunOssService;

    @Override
    protected String getCollectionName() {
        return "filesystemConfig";
    }

    @Override
    public String uploadFile(MultipartFile file) throws Exception {
        OpenContext openContext = ServiceContext.getCurrentContext().getOpenContext();
        String appId = openContext.getAppId();
        JSONObject jsonObject = checkAndGetConfig(appId);
        if (Objects.isNull(jsonObject)) {
            throw new ServiceException("校验上传配置参数失败");
        }

        String fileMd5 = Md5Util.getInstance().encrypt(file.getBytes());
        Query query = new Query();
        query.eq("file_md5", fileMd5);
        query.eq("app_id", appId);
        com.gitee.sop.sopauth.entity.Resource old = resourceMapper.getByQuery(query);

        if (old != null) {
            //存在相同资源，不需要再次上传，更新资源引用计数
            old.setReferenceCount(old.getReferenceCount() + 1);
            old.setUsedCount(old.getUsedCount() + 1);
            resourceMapper.update(old);
            String downloadUrl = aliyunOssService.downloadUrl(old.getDownloadUrl());
            return downloadUrl;
        }
        String extractFilename = FileUploadUtils.extractFilename(file);
        String extension = FileUploadUtils.getExtension(file);
        boolean upload = aliyunOssService.upload(extractFilename, file.getBytes());
        if (upload) {
            String downloadUrl = aliyunOssService.downloadUrl(extractFilename);
            com.gitee.sop.sopauth.entity.Resource newResource = new com.gitee.sop.sopauth.entity.Resource();
            newResource.setAppId(appId)
                    .setFileMd5(fileMd5)
                    .setFileName(FileUploadUtils.getFileNameByPath(extractFilename))
                    .setSize(file.getSize())
                    .setType(URLConnection.guessContentTypeFromName(extractFilename))
                    .setSubtype(extension)
                    .setDownloadUrl(downloadUrl)
                    .init();
            resourceMapper.save(newResource);
            return downloadUrl;
        }
        return null;
    }

    /**
     * 校验文件模板是否可正常使用
     *
     * @param appId 应用ID
     * @return
     */
    public JSONObject checkAndGetConfig(String appId) {
        List<MongoQuery> mongoQueries = new ArrayList<>();
        mongoQueries.add(new MongoQuery("appId", appId));
        mongoQueries.add(new MongoQuery("status", TemplateStatus.normal.getCode()));
        JSONObject jsonObject = mongoDbUtil.queryOne(getCollectionName(), mongoQueries, JSONObject.class);
        if (Objects.nonNull(jsonObject)) {
            String templateType = jsonObject.getString("templateType");
            Date startTime = jsonObject.getDate("startTime");
            Date endTime = jsonObject.getDate("endTime");
            Date currDate = new Date();
            if (currDate.after(startTime) && currDate.before(endTime)) {
                AliOssProperties aliOssProperties = new AliOssProperties();
                ObjectUtil.switchAllFieldValue(aliOssProperties, jsonObject);
                this.aliyunOssService = new AliyunOssService(aliOssProperties);
                return jsonObject;
            }
        }
        return null;
    }
}
